#pragma once
#include "socked.hpp"
#include "Request.hpp"
#include <thread>
#include <functional>
#include <sys/types.h>
#include <sys/socket.h>
#include <unordered_map>
#include <fstream>

class HttpServer
{
public:
    HttpServer()
        : socket_(8081)
    {
        // 初始化Connect-Type字段
        connect_type_.insert(pair<string, string>("html", "text/html"));
        connect_type_.insert(pair<string, string>("jpg", "image/jpeg"));
    }
    ~HttpServer()
    {
    }

    void Strat()
    {
        socket_.Socket();
        socket_.Bind();
        socket_.Listen();
        while (1)
        {
            socket_.Accept();
            cout << "get connect" << endl;
            thread th(Httpfunc, socket_.lis_sockfd_, connect_type_);
            th.detach();
        }
    }

    static void Httpfunc(int sockfd, unordered_map<string, string> connect_type)
    // 接收和处理请求
    {
        char buf[10240];
        // 接收请求
        int n = recv(sockfd, buf, sizeof(buf) - 1, 0);
        if (n > 0)
        {
            buf[n] = 0;
            // cout << buf << endl;;
            //   对请求的数据作处理，分割。分为 --请求行\r\n --请求报头\r\n --\r\n(空行) --请求正文
            Request req;
            req.deserialize(buf);
            // //打印请求报文
            // cout << "---------------------------------" << endl;
            // cout << "Method: " << req.method_ << " url: " << req.path_ << " HttpVision: " << req.http_version_ << endl;
            // for(int i = 1; i < req.head_.size(); i++)
            // {
            //     cout << req.head_[i] << endl;
            // }
            // cout << req.text_ << endl;

            // 发送页面
            string text = ReadHtml(req.path_);
            string Response;
            if (text.empty())
            {
                text = ReadHtml(req.err_path_);
                Response = "HTTP/1.1 404 NotFound\r\n";
            }
            else
            {
                // Response = "HTTP/1.1 302 Found\r\n"; // 状态行
                Response = "HTTP/1.1 200 OK\r\n"; // 状态行
            }

            Response += "Content-length: "; // 响应报头
            Response += to_string(text.size());
            Response += "\r\n";

            string ConnectType = GetConnectType(req.path_, connect_type);
            Response += "Connect-Type: ";
            Response += ConnectType;
            Response += "\r\n";

            // Response += "Location: https://www.qq.com\r\n";

            Response += "Set-Cookie: name=jjyy&&psw=12345\r\n";


            Response += "\r\n"; // 空行

            Response += text; // 响应正文

            cout << Response;
            send(sockfd, Response.c_str(), Response.size(), 0);
        }
        close(sockfd);
        return;
    }

    // 读取网页文件
    static string ReadHtml(const string &path)
    {
        ifstream in(path);
        if (!in.is_open())
            return "";
        string content;
        string line;
        while (getline(in, line))
        {
            content += line;
        }

        // //二进制读写，读图片
        // std::ifstream in(path, std::ios::binary);
        // if(!in.is_open()) return "";

        // in.seekg(0, std::ios_base::end);
        // auto len = in.tellg();
        // in.seekg(0, std::ios_base::beg);

        // std::string content;
        // content.resize(len);

        // in.read((char*)content.c_str(), content.size());
        in.close();
        return content;
    }

    static string GetConnectType(string &path, unordered_map<string, string> connect_type)
    {
        size_t pos = path.rfind('.');
        if (pos == string::npos)
            return "";
        else
        {
            string ret = path.substr(pos + 1);
            return connect_type[ret];
        }
    }

private:
    Sock socket_;
    unordered_map<string, string> connect_type_;
};